package com.hdp.kotlin_samples.base

/**
 * author:hdp
 * on:2019/6/12:17:55
 * desc:Kotlin中的集合
 *
 * Kotlin中的集合用于在一个单元中存储一组相关对象。
 *
 * 通过使用集合，可以存储，检索操作和聚合数据。
 *
 * Kotlin中大致分为两种不同集合的形式，可变的和不可变的
 *      可变           《==》            不可变
 *    Collection<E>                MutableCollection<E>
 *    List<E>                      MutableList<E>
 *    Set<E>                       MutableSet<E>
 *    Map<E>                       MutableMap<E>
 *
 *  1、集合的创建：不可变集合：xxxOf()，注意：首字母小写
 *
 *  2、可变集合：mutableXXXOf(),注意：首字母小写
 *
 *  3、集合遍历：
 *      1）：通过iterator遍历
 *      2）：通过内联扩展函数forEach{}
 *      3）：通过forEachIndexed { index, value ->  }带下标遍历
 *
 *  4、一些很有用的集合操作符
 *      1）：getOrNull：获取索引所在的元素，没有就返回nul
 *      2）：all:如果全部元素与判断条件相符，则 返回true
 *      3）：average:求集合的平均值(元素之和/元素大小)。仅限（Byte，Short，Int，Long，Float,Double）
 *      5）：contain:如果指定元素可以在集合找到，则 返回true
 *      6）：containsAll:如果指定集合所有元素都可以在目标集合找到，则 返回true
 *      7）：distinct:返回一个只包含不同元素的数组(去重，就是转换成set，再转回来)   注："不改变原集合，返回新的集合"
 *      8）：filter:筛选出所有符合条件的元素      注："不改变原集合，返回新的集合"
 *      9）：filterIndexed：筛选出所有符合条件的元素（条件多了一个索引参数）
 *      10)：filterNot：筛选出所有不符合条件的元素
 *      11）：filterNotNull：筛选出所有不为null的元素
 *      12）：firstOrNull：返回第一个满足条件的元素，没有，则 返回Null
 *      13）：Any:如果至少有一个元素与判断条件相符，则 返回true
 *      14）：groupBy:返回一个根据给定函数分组后的map
 *      15）：map：返回一个每个元素都根据给定函数条件转换的新的集合    注："不改变原集合，返回新的集合"
 *      16）：mapNotNull：同map。但是，元素转换不包含Nullf
 *      17）：flatMap：遍历所有的元素 ，每一个元素操作后返回一个Iterable,最后把所有的Iterator放在一个集合中(用于多维数组按条件打平)
 *      18）：partition：把一个指定的集合分割成2个。第一个集合是所有符合指定函数条件的，第二个集合是所有不符合指定条件的集合（有些场景很有用）
 *      ......
 *
 *
 */
fun main() {
//    test_immutable()
//    test_mutable()
//    testGetOrNull()
//    testAll()
//    testAny()
//    testContainsAll()
//    testDistinct()
//    testFilter()
//    testGroupBy()
//    testMap()
//    testFlatMap()
    testPartition()
}

/**
 * 创建不可变集合,只读
 */
private fun test_immutable() {
    //listof()
    var list1 = listOf<Int>(3, 3, 4, 5, 5, 6)
    println(list1[0])
    //setOf()
    var set1 = setOf<Int>(12, 3, 231, 43, 25)
    set1.forEach { println("$it ") }
    //mapOf()
    var map1 = mapOf<Int, String>(1 to "Java", 2 to "Kotlin", 3 to "Python")
    map1.entries.forEach { println("${it.key}==${it.value}") }
}

/**
 * 创建可变的集合，读写
 */
private fun test_mutable() {
    //listof()
    var list1 = mutableListOf<Int>(3, 3, 4, 5, 5, 6)
    list1[0] = 888
    println(list1[0])
    //setOf()
    var set1 = mutableSetOf<Int>(12, 3, 231, 43, 25)
    set1.add(999)
    set1.forEach { println("$it ") }
    //mapOf()
    var map1 = mutableMapOf<Int, String>(1 to "Java", 2 to "Kotlin", 3 to "Python")
    map1.put(4, "JavaScript")
    map1.entries.forEach { println("${it.key}==${it.value}") }
}

private fun testGetOrNull() {
    val list = mutableListOf("132", "java", "kotlin", "python")
    println("========testGetOrNull======")
    println(list.getOrNull(0))
    println(list.getOrNull(11))
}

private fun testAll() {
    val list = listOf(1, 2, 3, 4, 5, 6)
    println("========testAll======")
    val result = list.all { it < 10 }
    println("所有元素都小于10：$result")
}

//如果至少有一个元素与判断条件相符，则 返回true
private fun testAny() {
    println("========testAny======")
    val list = listOf(1, 2, 3, 4, 5, 6, 11)
    val result = list.any { it > 10 }
    println("有一个元素大于10：$result")

}


//如果指定集合所有元素都可以在目标集合找到，则 返回true
private fun testContainsAll() {
    println("========testContainsAll======")
    val list1 = listOf(123, 4, 5, 66, 7, 8, 9)
    val list2 = listOf(123, 4, 5, 66, 120)
    println("list1.containsAll test2:${list1.containsAll(list2)}")
}

//返回一个只包含不同元素的数组(去重)
private fun testDistinct() {
    println("========testDistinct======")
    val list1 = listOf(123, 4, 5, 66, 7, 8, 9, 5, 8, 9)
    println("list1:$list1")
    val list2 = list1.distinct()
    println("list1 after distinct:$list1")
    println("list2 after distinct:$list2")
}

//返回一个只包含不同元素的数组(去重)
private fun testFilter() {
    println("========testFilter======")
    var list1 = listOf(123, 4, 5, 66, 7, 8, 9, 13, 12, 44, 456)
    println("list1:$list1")
    val list2 = list1.filter { it > 10 }
    println("list1 after filter:$list1")
    println("list2 after distinct:$list2")
}

//返回一个根据给定函数分组后的map
private fun testGroupBy() {
    println("========testGroupBy======")
    //定义一个User实体类
    data class User(val name: String, val dept: String)

    val userList = listOf<User>(
        User("张三", "研发"),
        User("李四", "研发"),
        User("王五", "质检"),
        User("小米", "质检"),
        User("小明", "研发"),
        User("小红", "人力"),
    )
    println("========userList:$userList")
    println("========userList group by dept")
    println(userList.groupBy { it.dept })

}

//返回一个每个元素都根据给定函数条件转换的新的集合
private fun testMap() {
    println("========testMap======")
    val list = listOf("java", "kotlin", "python")
    val list2 = list.map { it + "是最棒的" }
    println("list:$list")
    println("list2:$list2")
    println("list after map:$list")

}

//flatMap：遍历每一个元素，并铺平元素
private fun testFlatMap() {
    println("========testFlatMap======")
    val list = listOf(listOf(10, 20), listOf(30, 40), listOf(50, 60))
    val mapList = list.map { element -> element.toString() }
    val flatMapList = list.flatMap { it.map { it + 10 } }
    println("mapList:$mapList")
    println("flatMapList:$flatMapList")
}

private fun testPartition() {
    println("==========testPartition=========")
    val list = listOf(1, 2, 3, 4, 5, 10, 11, 12, 13)
    val partition = list.partition { it > 10 }
    println("partion.first:${partition.first}")
    println("partion.second:${partition.second}")
}